package com.zpp.gobang.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zpp.gobang.game.MatchRequest;
import com.zpp.gobang.game.MatchResponse;
import com.zpp.gobang.game.Matcher;
import com.zpp.gobang.game.OnlineUserManager;
import com.zpp.gobang.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
public class MatchAPI extends TextWebSocketHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        //玩家上线，加入到OnlineUserManager

        try {
            //1.先获取到当前用户的身份信息
            User user= (User) session.getAttributes().get("user");
            //2.判断当前是否存在多开
            //没有多开 是同一个人

            //存在多开
            if(onlineUserManager.getFromGameHall(user.getUserId()) != null||
                onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setMessage("repeatLogin");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                return;
            }


            //3.把玩家信息设置为在线状态
            onlineUserManager.enterGameHall(user.getUserId(),session);
            System.out.println("玩家 "+ user.getUsername() + " 进入游戏大厅");

        }catch (NullPointerException e){  //捕获异常，获取的user可能存在空
            System.out.println("[MatchAPI.afterConnectionEstablished] 用户未登录");
            //e.printStackTrace();
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

        User user= (User) session.getAttributes().get("user");
        //获取客户端给服务器发送的数据
        String payload = message.getPayload();
        //当前的载荷数据是一个JSON格式的字符串，需要把它转成Java对象，MatchRequest
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);

        MatchResponse response = new MatchResponse();
        if(request.getMessage().equals("startMatch")) {
            //进入匹配队列
            matcher.add(user);
            //把玩家的信息放入匹配队列之后,就可以返回一个响应给客户端
            response.setOk(true);
            response.setMessage("startMatch");

        }else if(request.getMessage().equals("stopMatch")) {
            //退出匹配队列
            matcher.remove(user);
            //移除之后返回一个响应给客户端
            response.setOk(true);
            response.setMessage("stopMatch");

        }else {
            //非法请求
            response.setOk(false);
            response.setReason("非法匹配请求");
        }
        String json = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(json));

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        //玩家下线，从OnlineUserManager中删除

        try {
            User user= (User) session.getAttributes().get("user");
            //判断要下线的用户是否是多开用户下线，防止误删
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if(tmpSession == session){
                onlineUserManager.exitGameHall(user.getUserId());
            }
            matcher.remove(user); //如果用户连接中断或者关闭退出，也需要把玩家移除匹配队列
            System.out.println("游戏大厅连接异常，用户： "+user.getUsername() + "下线");

        }catch (NullPointerException e){
            System.out.println("[MatchAPI.handleTransportError] 用户未登录");

            /*e.printStackTrace();
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));*/
        }

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        //玩家下线，从OnlineUserManager中删除

        try {
            User user= (User) session.getAttributes().get("user");
            //判断要下线的用户是否是多开用户下线，防止误删
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if(tmpSession == session){  //避免在多开的情况下，第二个用户的退出把第一个用户也退出了
                onlineUserManager.exitGameHall(user.getUserId());
            }
            matcher.remove(user); //如果用户连接中断或者关闭退出，也需要把玩家移除匹配队列
            System.out.println("退出游戏大厅  用户： "+user.getUsername() +"下线");
        }catch (NullPointerException e){
            System.out.println("[MatchAPI.afterConnectionClosed] 用户未登录");

            //关闭后无法在给客户端发送响应了
            //e.printStackTrace();
            /*MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("用户未登录");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));*/
        }
    }
}
